_require local "../../basis.smi"
_require local "../../ml-yacc/lib/base.sig"
_require local "./utils.smi"
_require local "./utils.sig"
_require local "./sigs.sml"
_require "./grammar.smi"

structure Core =
struct
  structure Grammar =
  struct
    datatype term = datatype IntGrammar.Grammar.term
    datatype nonterm = datatype IntGrammar.Grammar.nonterm
    datatype symbol = datatype IntGrammar.Grammar.symbol
    datatype grammar = datatype IntGrammar.Grammar.grammar
  end
  structure IntGrammar =
  struct
    structure Grammar =
    struct
      datatype term = datatype IntGrammar.Grammar.term
      datatype nonterm = datatype IntGrammar.Grammar.nonterm
      datatype symbol = datatype IntGrammar.Grammar.symbol
      datatype grammar = datatype IntGrammar.Grammar.grammar
    end
    structure SymbolAssoc =
    struct
      type 'a table = 'a IntGrammar.SymbolAssoc.table
      type key = IntGrammar.SymbolAssoc.key
      val size : 'a table -> int
      val empty : 'a table
      val exists : (key * 'a table) -> bool
      val find : (key * 'a table)  ->  'a option
      val insert: ((key * 'a) * 'a table) -> 'a table
      val make_table : (key * 'a ) list -> 'a table
      val make_list : 'a table -> (key * 'a) list
      val fold : ((key * 'a) * 'b -> 'b) -> 'a table -> 'b -> 'b
    end
    structure NontermAssoc =
    struct
      type 'a table = 'a IntGrammar.NontermAssoc.table
      type key = IntGrammar.NontermAssoc.key
      val size : 'a table -> int
      val empty : 'a table
      val exists : (key * 'a table) -> bool
      val find : (key * 'a table)  ->  'a option
      val insert: ((key * 'a) * 'a table) -> 'a table
      val make_table : (key * 'a ) list -> 'a table
      val make_list : 'a table -> (key * 'a) list
      val fold : ((key * 'a) * 'b -> 'b) -> 'a table -> 'b -> 'b
    end
    datatype rule = datatype IntGrammar.rule
    val gtTerm : Grammar.term * Grammar.term -> bool
    val eqTerm : Grammar.term * Grammar.term -> bool
    val gtNonterm : Grammar.nonterm * Grammar.nonterm -> bool
    val eqNonterm : Grammar.nonterm * Grammar.nonterm -> bool
    val gtSymbol : Grammar.symbol * Grammar.symbol -> bool
    val eqSymbol : Grammar.symbol * Grammar.symbol -> bool
    val DEBUG : bool
    val prRule : (Grammar.symbol -> string) * (Grammar.nonterm -> string) *
                 (string -> 'b) -> rule -> unit
    val prGrammar : (Grammar.symbol -> string)*(Grammar.nonterm -> string) *
                    (string -> unit) -> Grammar.grammar -> unit
  end
  datatype item = ITEM of {rule: IntGrammar.rule, dot: int,
                           rhsAfter: Grammar.symbol list}
  val eqItem : item * item -> bool
  val gtItem : item * item -> bool
  val insert : item * item list -> item list
  val union : item list * item list -> item list
  datatype core = CORE of item list * int
  val gtCore : core * core -> bool
  val eqCore : core * core -> bool
  val prItem : (Grammar.symbol -> string) * (Grammar.nonterm -> string) *
               (string -> unit) -> item -> unit
  val prCore : (Grammar.symbol -> string) * (Grammar.nonterm -> string) *
               (string -> unit) -> core -> unit
end
